package com.sunrise.bean;

import com.github.dvdme.ForecastIOLib.FIODataPoint;
import com.sunrise.boundary.CalendarManager;
import com.sunrise.boundary.EventManager;
import com.sunrise.boundary.InvitationRequestManager;
import com.sunrise.boundary.LocationManager;
import com.sunrise.boundary.UserManager;
import com.sunrise.boundary.WeatherManager;
import com.sunrise.entity.Event;
import com.sunrise.entity.InvitationRequest;
import com.sunrise.entity.Location;
import com.sunrise.entity.User;
import java.io.Serializable;
import static java.lang.Math.round;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import org.primefaces.context.RequestContext;

import org.primefaces.event.ScheduleEntryMoveEvent;
import org.primefaces.event.ScheduleEntryResizeEvent;
import org.primefaces.event.SelectEvent;
import org.primefaces.model.DefaultScheduleModel;
import org.primefaces.model.ScheduleModel;
import org.primefaces.event.UnselectEvent;
import org.primefaces.model.ScheduleEvent;

@ManagedBean
@ViewScoped
public class CalendarBean implements Serializable {

    final long _SECONDSONEDAY = 86400;
    final long _SECONDSTHREEDAYS = 259200;
    final long _SECONDSSEVENDAYS = 640800;

    // ERROR MESSAGES  
    static final String _ERROR_END_DATE_BEFORE_START_DATE = "Start date must be before end date";
    static final String _ERROR_START_DATE_CANNOT_BE_IN_THE_PAST = "Start Date cannot be in the past";
    static final String _ERROR_OUTDOOR_SELECTED_LOC = "The location of an outdoor event must be selected from the suggestions";  
    static final String _ERROR_END_DATE_CANNOT_BE_IN_THE_PAST = "End Date cannot be in the past";
    static final String _ERROR_TITLE_CANNOT_BE_EMPTY = "Title cannot be empty";

    //INFO MESSAGES
    static final String _INFO_START_DATE_TOO_CLOSE_NO_TIMER_CREATED = "Start Date too close, no weather alerts will be sent";
    static final String _INFO_START_DATE_TOO_FAR_NO_WEATHER = "Start Date too far, impossible to retrieve weather information";
    
    List<FIODataPoint> dailyForecast;
    final SimpleDateFormat dateFormatterForecastIO = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
    final SimpleDateFormat dateFormatterForDisplay = (SimpleDateFormat) DateFormat.getDateInstance(DateFormat.MEDIUM, Locale.UK);

    ScheduleModel scheduleModel;

    @EJB
    EventManager eventManager;

    @EJB
    UserManager userManager;

    @EJB
    CalendarManager calendarManager;

    @EJB
    LocationManager locationManager;
    
    @EJB
    WeatherManager weatherManager;

    @EJB
    InvitationRequestManager invRqMngr;

    //private EmailSessionBean emailSessionBean = new EmailSessionBean();
    Event event = new Event();

    String tmpLat = "";
    String tmpLon = "";
    String tmpLocDescription = "";

    //private Date tmpStartDate = null;
    List<User> invitees;

    User searchedUser;

    public User getSearchedUser() {
        return searchedUser;
    }

    public void setSearchedUser(User searchedUser) {
        this.searchedUser = searchedUser;
    }

    public String getTmpLat() {
        return tmpLat;
    }

    public void setTmpLat(String tmpLat) {
        this.tmpLat = tmpLat;
    }

    public String getTmpLon() {
        return tmpLon;
    }

    public void setTmpLon(String tmpLon) {
        this.tmpLon = tmpLon;
    }

    public String getTmpLocDescription() {
        return tmpLocDescription;
    }

    public void setTmpLocDescription(String tmpLocDescription) {
        this.tmpLocDescription = tmpLocDescription;
    }

    public boolean shouldRenderCarousel() {
        boolean dateCorrect = false;

        Date today = new Date();
        //long dateDiff1 = DateDiff(today, event.getStartDate());
        long dateDiff = dateDiffSeconds(today, event.getStartDate());

        if (event != null && event.getStartDate() != null
                && event.getStartDate().after(today)
                && (dateDiff > 0) && (dateDiff < _SECONDSSEVENDAYS)) {
            dateCorrect = true;
        }

        return (event.isOutdoor()
                && event.getLocation() != null
                && event.getLocation().getPlaceIdentifier()!= null
                && event.getLocation().getDescription() != null
                && event.getLocation().getLatitude() != null
                && event.getLocation().getLongitude() != null
                && !event.getLocation().getPlaceIdentifier().isEmpty()
                && !event.getLocation().getDescription().isEmpty()
                && !event.getLocation().getLatitude().isEmpty()
                && !event.getLocation().getLongitude().isEmpty()
                && event.getLocation().getDescription().equals(tmpLocDescription)
                && dateCorrect);
    }

    @PostConstruct
    public void init() {

        //String jsfVersion = FacesContext.class.getPackage().getImplementationVersion();
        eventManager.setUser(userManager.getLoggedUser());

        //timerBean.stopAllTimers();
        //emailSessionBean.sendEmail("andrea.bellotti@outlook.com", "ciao", "facciamo una \nprova");
        scheduleModel = new DefaultScheduleModel();

        // events owned by the user
        List<Event> events = eventManager.findUserEvents();

        for (Event event : events) {
            event.setLoadedByOwner(true);
            scheduleModel.addEvent(event);
        }

        // events accepted by the user (he is a guest)
        List<Event> eventsInvitedAndAccepted = eventManager.findUserInvitedAndAcceptedEvents();
        for (Event event : eventsInvitedAndAccepted) {
            event.setLoadedByOwner(false);
            event.setStyleClass("guestevent");
            scheduleModel.addEvent(event);
        }

        Event rescheduleEvent = (Event) FacesContext.getCurrentInstance().getExternalContext().getFlash().get("rescheduleEvent");

        if (rescheduleEvent != null) {

            event = rescheduleEvent;

            if (dailyForecast != null) {
                dailyForecast.clear();
            }
            if (invitees != null) {
                invitees.clear();
            }
            for (InvitationRequest invitationRequest : event.getInvitationRequests()) {
                if(invitees == null) invitees = new ArrayList<>();
                invitees.add(invitationRequest.getRecipient());
            }

            tmpLat = "";
            tmpLon = "";
            tmpLocDescription = event.getLocation().getDescription();

            if (event.isOutdoor()) {
                checkWeather();
            }

            RequestContext context = RequestContext.getCurrentInstance();
            context.update("eventDetails");
            context.execute("PF('eventDialog').show();activateGeocomplete();");
        }
    }

    public boolean isEventEditable(Event event) {
        com.sunrise.entity.Calendar cal = event.getCalendar();

        if (cal == null) {
            // the event is in the process of being created
            return true;
        } else {
            return (userManager.getLoggedUser() == cal.getOwner());
        }
    }

    public Date getInitialDate() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(calendar.get(Calendar.YEAR), Calendar.FEBRUARY, calendar.get(Calendar.DATE), 0, 0, 0);

        return calendar.getTime();
    }

    public ScheduleModel getScheduleModel() {
        return scheduleModel;
    }

    private Calendar today() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DATE), 0, 0, 0);

        return calendar;
    }

    public Event getEvent() {
        return event;
    }

    public void setEvent(Event event) {
        this.event = event;
    }

    private void updateInvReq(List<InvitationRequest> oldInvitationRequests, List<User> newInvitees, Event e) {
        if (newInvitees == null || newInvitees.isEmpty()) {
            invRqMngr.deleteInvitationRequestsForEvent(e);
            //e.setInvitationRequests(null);
            return;
        }

        if (oldInvitationRequests == null || oldInvitationRequests.isEmpty()) {
            List<InvitationRequest> invitationRequestList = InvitationRequest.buildWithInviteesAndEvent(newInvitees, e);
            e.setInvitationRequests(invitationRequestList);
            /*
            for (InvitationRequest ir : invitationRequestList) {
                invRqMngr.save(ir);
            }
            */
            return;
        }

        List<User> oldInvitees = invRqMngr.invitedUsers(oldInvitationRequests);
        List<InvitationRequest> invitationsToRemove = new ArrayList<InvitationRequest>();
        
        // cancellare le invitation request che erano in old e non sono più in newInvitees
        for (InvitationRequest invReq : oldInvitationRequests) {
            if (!newInvitees.contains(invReq.getRecipient())) {
                //invRqMngr.delete(invReq);
                invitationsToRemove.add(invReq);
                //e.removeInvitationRequest(invReq);
            }
        }
        
        for (InvitationRequest invitationReq : invitationsToRemove) {
            e.removeInvitationRequest(invitationReq);
            invRqMngr.delete(invitationReq);
        }
        
        // aggiungere le invitation requests per utenti new che non c'erano nelle old
        for (User newInvitee : newInvitees) {
            if (! oldInvitees.contains(newInvitee)) {
                InvitationRequest ir = new InvitationRequest(newInvitee, e);
                e.addInvitationRequest(ir);
            }
        }
    }

    public void addEvent(ActionEvent actionEvent) {
        if (eventIsValid()) {
            Date today = new Date();

            List<com.sunrise.entity.Calendar> calendars;
            calendars = calendarManager.findByUser(userManager.getLoggedUser());

            if (calendars.size() > 0) {
                event.setCalendar(calendars.get(0));

//                List<InvitationRequest> invitationRequestList = InvitationRequest.buildWithInviteesAndEvent(invitees, event);
//                invRqMngr.deleteInvitationRequestsForEvent(event);
                updateInvReq(event.getInvitationRequests(), invitees, event);
                
//                event.setInvitationRequests(invitationRequestList);
                // checks for timers
                if (event.isOutdoor()) {
                    long dateDiff = dateDiffSeconds(today, event.getStartDate());

                    if (dateDiff > _SECONDSTHREEDAYS) {
                        event.setCheckedThreeDays(false);
                        event.setCheckedOneDay(false);
                    } else if (60*60*2 < dateDiff && dateDiff < _SECONDSTHREEDAYS) {
                        event.setCheckedThreeDays(true);
                        event.setCheckedOneDay(false);
                    } else {
                        event.setCheckedThreeDays(true);
                        event.setCheckedOneDay(true);
                        calendarManager.displayInfo(FacesContext.getCurrentInstance(), _INFO_START_DATE_TOO_CLOSE_NO_TIMER_CREATED);
                    }
                } else {
                    if (!event.getLocation().getDescription().equals(tmpLocDescription)) {
                        event.getLocation().setLatitude("");
                        event.getLocation().setLongitude("");
                        event.getLocation().setPlaceIdentifier("");
                    }
                }

                if (event.getIdentifier() == null) { 
                    // new event
                    eventManager.save(event);
                    scheduleModel.addEvent(event);
                } else { 
                    // edit event
                    event = eventManager.update(event);

                    List<ScheduleEvent> events = scheduleModel.getEvents();
                    for (ScheduleEvent scheduleEvent : events) {
                        Event tmpEvent = (Event) scheduleEvent;
                        if (tmpEvent.getIdentifier().equals(event.getIdentifier())) {
                            event.setId(tmpEvent.getId());
                        }
                    }
                    scheduleModel.updateEvent(event);
                }
                
                
            }

            event = new Event();

            RequestContext context = RequestContext.getCurrentInstance();
            context.execute("PF('myschedule').update();PF('eventDialog').hide();");
        }
    }

    public boolean eventIsValid() {
        Date today = new Date();
        boolean validEvent = true;

        if (event.getTitle().isEmpty()) {
            calendarManager.displayError(FacesContext.getCurrentInstance(), _ERROR_TITLE_CANNOT_BE_EMPTY);
            validEvent = false;
        }
        if (event.getStartDate().before(today)) {
            calendarManager.displayError(FacesContext.getCurrentInstance(), _ERROR_START_DATE_CANNOT_BE_IN_THE_PAST);
            validEvent = false;
        }
        if (event.getEndDate().before(today)) {
            calendarManager.displayError(FacesContext.getCurrentInstance(), _ERROR_END_DATE_CANNOT_BE_IN_THE_PAST);
            validEvent = false;
        }
        if (event.getStartDate().after(event.getEndDate())) {
            calendarManager.displayError(FacesContext.getCurrentInstance(), _ERROR_END_DATE_BEFORE_START_DATE);
            validEvent = false;
        }
        if (event.isOutdoor() && 
                ((event.getLocation().getDescription() == null) 
                || (event.getLocation().getDescription().isEmpty())
                || (!event.getLocation().getDescription().equals(tmpLocDescription))
                || (event.getLocation().getPlaceIdentifier().isEmpty())
                || (event.getLocation().getLatitude() == null) 
                || (event.getLocation().getLongitude() == null)
                || (event.getLocation().getLatitude().isEmpty())
                || (event.getLocation().getLongitude().isEmpty()))) {
            
            calendarManager.displayError(FacesContext.getCurrentInstance(), _ERROR_OUTDOOR_SELECTED_LOC);
            validEvent = false;
        }   

        return validEvent;
    }

    public void deleteEvent() {
        if (event.getIdentifier() != null) {
            boolean deleted = eventManager.deleteEvent(event);
            scheduleModel.deleteEvent(event);
        }

        RequestContext context = RequestContext.getCurrentInstance();
        context.execute("PF('myschedule').update();PF('eventDialog').hide();");
        event = new Event();
    }

    public void onEventSelect(SelectEvent selectEvent) {

        event = (Event) selectEvent.getObject();

        Event tmpEvent = eventManager.findEventByIdentifier(event.getIdentifier());
        
        if (tmpEvent != null) {
            event.setStartDate(tmpEvent.getStartDate());
            event.setEndDate(tmpEvent.getEndDate());
            event.setLocation(tmpEvent.getLocation());
        }
        
        if (dailyForecast != null) {
            dailyForecast.clear();
        }
        if (invitees != null) {
            invitees.clear();
        }
        
        for (InvitationRequest invitationRequest : event.getInvitationRequests()) {
            if(invitees == null) invitees = new ArrayList<>();
            invitees.add(invitationRequest.getRecipient());
        }

        tmpLat = "";
        tmpLon = "";
        tmpLocDescription = event.getLocation().getDescription();

        checkWeather();
    }

    public void onDateSelect(SelectEvent selectEvent) {
        Calendar cal = Calendar.getInstance(); // creates calendar
        cal.setTime((Date) selectEvent.getObject()); // sets calendar time/date
        cal.add(Calendar.HOUR_OF_DAY, 12);

        Date startDate = cal.getTime();
        cal.add(Calendar.HOUR_OF_DAY, 1);
        Date endDate = cal.getTime();

        event = new Event(startDate, endDate);

        if (dailyForecast != null) {
            dailyForecast.clear();
        }
        if (invitees != null) {
            invitees.clear();
        }

        tmpLat = "";
        tmpLon = "";
        tmpLocDescription = "";
        //tmpStartDate = event.getStartDate();
    }

    public void onEventMove(ScheduleEntryMoveEvent event) {
        Event movedEvent = (Event) event.getScheduleEvent();

        if (movedEvent.isOutdoor()) {
            Date today = new Date();

            long dateDiff = dateDiffSeconds(today, movedEvent.getStartDate());

            if (dateDiff > _SECONDSTHREEDAYS) {
                movedEvent.setCheckedThreeDays(false);
                movedEvent.setCheckedOneDay(false);
            } else if (dateDiff > _SECONDSONEDAY) {
                movedEvent.setCheckedThreeDays(true);
                movedEvent.setCheckedOneDay(false);
            } else {
                movedEvent.setCheckedThreeDays(true);
                movedEvent.setCheckedOneDay(true);
                calendarManager.displayInfo(FacesContext.getCurrentInstance(), _INFO_START_DATE_TOO_CLOSE_NO_TIMER_CREATED);
            }

            eventManager.update(movedEvent);
        }
    }

    public void onEventResize(ScheduleEntryResizeEvent event) {
     
    }

    public void handleOutdoor() {

        Date today = new Date();

        if (event.getStartDate().before(today)) {
            calendarManager.displayError(FacesContext.getCurrentInstance(), _ERROR_START_DATE_CANNOT_BE_IN_THE_PAST);
        }
        if (event.getEndDate().before(today)) {
            calendarManager.displayError(FacesContext.getCurrentInstance(), _ERROR_END_DATE_CANNOT_BE_IN_THE_PAST);
        }
        if (event.getStartDate().after(this.event.getEndDate())) {
            calendarManager.displayError(FacesContext.getCurrentInstance(), _ERROR_END_DATE_BEFORE_START_DATE);
        }    

        if (event.isOutdoor()) {
            if (event.getLocation().getDescription() != null && !event.getLocation().getDescription().isEmpty()) {
                //DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");

                //long dateDiff1 = DateDiff(today, event.getStartDate());
                //long dateDiff2 = dateDiffHours(today, event.getStartDate());
                long dateDiff = dateDiffSeconds(today, event.getStartDate());

                if (event.getStartDate().after(today)) {
                    if ((dateDiff > 0) && (dateDiff < _SECONDSSEVENDAYS)) {

                        if (event.getLocation().getDescription() != null && !event.getLocation().getDescription().isEmpty()
                                && event.getLocation().getLatitude() != null && event.getLocation().getLongitude() != null
                                && !event.getLocation().getLatitude().isEmpty() && !event.getLocation().getLongitude().isEmpty()) {
                            checkWeather();
                        } else {
                            calendarManager.displayError(FacesContext.getCurrentInstance(), _ERROR_OUTDOOR_SELECTED_LOC);
                        }
                    } else {
                        calendarManager.displayInfo(FacesContext.getCurrentInstance(), _INFO_START_DATE_TOO_FAR_NO_WEATHER);
                    }
                }
            } else {
                calendarManager.displayError(FacesContext.getCurrentInstance(), _ERROR_OUTDOOR_SELECTED_LOC);
            }
        }

        RequestContext context = RequestContext.getCurrentInstance();
        context.execute("activateGeocomplete();");
    }

    public void handleLocationSelection() {
        Date today = new Date();
        
        tmpLocDescription = event.getLocation().getDescription();
        
        if (event.getStartDate().before(today)) {
            calendarManager.displayError(FacesContext.getCurrentInstance(), _ERROR_START_DATE_CANNOT_BE_IN_THE_PAST);
        }
        if (event.getEndDate().before(today)) {
            calendarManager.displayError(FacesContext.getCurrentInstance(), _ERROR_END_DATE_CANNOT_BE_IN_THE_PAST);
        }
        if (event.getStartDate().after(event.getEndDate())) {
            calendarManager.displayError(FacesContext.getCurrentInstance(), _ERROR_END_DATE_BEFORE_START_DATE);
        }

        if (event.isOutdoor()) {
            //DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");

            //long dateDiff1 = DateDiff(today, event.getStartDate());
            //long dateDiff2 = dateDiffHours(today, event.getStartDate());
            long dateDiff = dateDiffSeconds(today, event.getStartDate());

            if ((dateDiff > 0) && (dateDiff < _SECONDSSEVENDAYS)) {

                if (event.getLocation().getLatitude() != null && event.getLocation().getLongitude() != null
                        && !event.getLocation().getLatitude().isEmpty() && !event.getLocation().getLongitude().isEmpty()) {
                    checkWeather();
                }
            } else {
                calendarManager.displayInfo(FacesContext.getCurrentInstance(), _INFO_START_DATE_TOO_FAR_NO_WEATHER);
            }
        }

        RequestContext context = RequestContext.getCurrentInstance();
        context.execute("activateGeocomplete();");
    }

    public String autoCompleteItemLabelForUser(User u) {
        if (u != null) {
            InvitationRequest invReq = event.findInvitationForUser(u);

            if (invReq != null) {
                String invState;
                if (!invReq.isViewed()) {
                    invState = "(pending)";
                } else if (invReq.isAccepted()) {
                    invState = "(accepted)";
                } else {
                    invState = "(declined)";
                }

                return u.getFullName() + " " + invState;
            } else {
                return u.getFullName();
            }
        } else {
            return "";
        }
    }

    public void handleGeocomplete() {
        if (event.getLocation().getDescription().isEmpty()) {
            event.setLocation(new Location());
            if (dailyForecast != null) {
                dailyForecast.clear();
            }
        }

        RequestContext context = RequestContext.getCurrentInstance();
        context.execute("activateGeocomplete();");
    }

    public void handleStartDateSelect(SelectEvent event) {
        Date date = (Date) event.getObject();
        Date today = new Date();

        if (date.before(today)) {
            calendarManager.displayError(FacesContext.getCurrentInstance(), _ERROR_START_DATE_CANNOT_BE_IN_THE_PAST);
        }
        if (this.event.getEndDate().before(today)) {
            calendarManager.displayError(FacesContext.getCurrentInstance(), _ERROR_END_DATE_CANNOT_BE_IN_THE_PAST);
        }        
        if (date.after(this.event.getEndDate())) {
            calendarManager.displayError(FacesContext.getCurrentInstance(), _ERROR_END_DATE_BEFORE_START_DATE);
        }
    }

    public void handleEndDateSelect(SelectEvent event) {
        Date date = (Date) event.getObject();
        Date today = new Date();

        if (this.event.getStartDate().before(today)) {
            calendarManager.displayError(FacesContext.getCurrentInstance(), _ERROR_START_DATE_CANNOT_BE_IN_THE_PAST);
        }
        if (date.before(today)) {
            calendarManager.displayError(FacesContext.getCurrentInstance(), _ERROR_END_DATE_CANNOT_BE_IN_THE_PAST);
        }
        if (date.before(this.event.getStartDate())) {
            calendarManager.displayError(FacesContext.getCurrentInstance(), _ERROR_END_DATE_BEFORE_START_DATE);
        }
    }

    public void checkWeather() {
        String latitude = event.getLocation().getLatitude();
        String longitude = event.getLocation().getLongitude();

        //avoid useless calls to the weather API
        if (event.isOutdoor() && latitude != null && longitude != null && !latitude.isEmpty() && !longitude.isEmpty() 
                && !latitude.equals(tmpLat) && !longitude.equals(tmpLon)) {
            dailyForecast = weatherManager.getWeatherForLocation(latitude, longitude);

            tmpLat = latitude;
            tmpLon = longitude;
        }
    }

    public List<FIODataPoint> getDailyForecast() {
        return dailyForecast;
    }

    public String iconForDay(FIODataPoint day) {
        String suffix = "";
        
        DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
        Date dayDate = weatherManager.dateStringForDay(day);   
        String dayDateString = dateFormat.format(dayDate);
        String eventDate = dateFormat.format(event.getStartDate());
        if (dayDateString.equals(eventDate)) suffix = "_chosen_day";
        
        return "/calendar/resources/img/" + day.icon().replace("\"", "") + suffix + ".svg";
    }

    public String dateStringForDay(FIODataPoint day) {
        Date dayDate;
        try {
            dayDate = dateFormatterForecastIO.parse(day.time());
        } catch (ParseException e) {
            dayDate = new Date();
        }

        return dateFormatterForDisplay.format(dayDate);
    }

    public String formatTemperature(Double temp) {
        return String.valueOf(round(temp));
    }

    /*
    public long DateDiff(Date lowerDate, Date higherDate) {
        if (higherDate != null && lowerDate != null) {
            long higherTime = higherDate.getTime();
            long lowerTime = lowerDate.getTime();
            long diffTime = higherTime - lowerTime;
            return diffTime / (1000 * 60 * 60 * 24);
        } else {
            return Long.MIN_VALUE;
        }
    }

    public long dateDiffHours(Date lowerDate, Date higherDate) {
        if (higherDate != null && lowerDate != null) {
            long higherTime = higherDate.getTime();
            long lowerTime = lowerDate.getTime();
            long diffTime = higherTime - lowerTime;
            return diffTime / (1000 * 60 * 60);
        } else {
            return Long.MIN_VALUE;
        }
    }

    public long dateDiffMinutes(Date lowerDate, Date higherDate) {
        if (higherDate != null && lowerDate != null) {
            long higherTime = higherDate.getTime();
            long lowerTime = lowerDate.getTime();
            long diffTime = higherTime - lowerTime;
            return diffTime / (1000 * 60);
        } else {
            return Long.MIN_VALUE;
        }
    }
    */

    public long dateDiffSeconds(Date lowerDate, Date higherDate) {
        if (higherDate != null && lowerDate != null) {
            long higherTime = higherDate.getTime();
            long lowerTime = lowerDate.getTime();
            long diffTime = higherTime - lowerTime;
            return diffTime / (1000);
        } else {
            return Long.MIN_VALUE;
        }
    }

    public List<User> getInvitees() {
        if (invitees == null) {
            invitees = new ArrayList<>();
        }
        return invitees;
    }

    public void setInvitees(List<User> invitees) {
        this.invitees = invitees;
    }

    public void selectInviteeListener(SelectEvent event) {
        User u = (User) event.getObject();
        getInvitees().add(u);
    }

    public void unselectInviteeListener(UnselectEvent event) {
        User u = (User) event.getObject();
        getInvitees().remove(u);
    }

    public List<User> completeInvitee(String query) {
        List<User> suggestions = userManager.findUserSuggestions(query, userManager.getLoggedUser());
        List<User> myinvitees = getInvitees();
        if (myinvitees != null) {
            suggestions.removeAll(myinvitees);
        }
        return suggestions;
    }
    
    public User getLoggedUser() {
        return userManager.getLoggedUser();
    }
}
